package ast.expr

import ast.SqlNode
import ast.order.SqlOrderBy
import ast.statement.select.SqlSelectQuery
import java.math.BigDecimal
import java.text.SimpleDateFormat
import java.util.*

/**
 * sql语法树：表达式父类
 */
sealed class SqlExpr : SqlNode

/**
 * sql语法树：二元运算表达式
 * @property left SqlExpr 二元运算左侧表达式
 * @property operator SqlBinaryOperator 二元运算符
 * @property right SqlExpr 二元运算右侧表达式
 */
data class SqlBinaryExpr(val left: SqlExpr, val operator: SqlBinaryOperator, val right: SqlExpr) : SqlExpr()

/**
 * sql语法树：标识符表达式
 * @property name String 标识符名称
 */
data class SqlIdentifierExpr(val name: String) : SqlExpr()

/**
 * sql语法树：属性表达式
 * @property owner String 所有者名称
 * @property name String 标识符名称
 */
data class SqlPropertyExpr(val owner: String, val name: String) : SqlExpr()

/**
 * sql语法树：NULL表达式
 * @property name String?
 */
data class SqlNullExpr(val name: String? = null) : SqlExpr() {
    override fun toString(): String {
        return "NULL"
    }
}

/**
 * sql语法树：字段通配符表达式（用于生成sql中的*）
 * @property owner String? 所有者名称
 */
data class SqlAllColumnExpr(val owner: String? = null) : SqlExpr()

/**
 * sql语法树：数值表达式
 * @property number Number 数值
 */
data class SqlNumberExpr(val number: Number) : SqlExpr() {
    override fun toString(): String {
        return number.toString()
    }
}

/**
 * sql语法树：时间表达式
 * @property date Date 时间
 */
data class SqlDateExpr(val date: Date) : SqlExpr() {
    override fun toString(): String {
        val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        return "'${format.format(date)}'"
    }
}

/**
 * sql语法树：字符表达式
 * @property text String 字符
 */
data class SqlCharExpr(val text: String) : SqlExpr() {
    override fun toString(): String {
        return "'${text.replace("'", "''")}'"
    }
}

/**
 * sql语法树：布尔表达式
 * @property boolean Boolean 布尔值
 */
data class SqlBooleanExpr(val boolean: Boolean) : SqlExpr() {
    override fun toString(): String {
        return boolean.toString()
    }
}

/**
 * sql语法树：列表表达式
 * @property items List<T> 表达式列表
 */
data class SqlListExpr<T : SqlExpr>(val items: List<T> = listOf()) : SqlExpr()

/**
 * sql语法树：聚合函数表达式
 * @property name String 函数名称
 * @property args MutableList<SqlExpr> 参数列表
 * @property distinct Boolean 是否去重
 * @property attributes MutableMap<String, SqlExpr> 属性列表
 * @property orderBy MutableList<SqlOrderBy> 排序规则列表
 */
data class SqlAggFunctionExpr(
    val name: String,
    val args: MutableList<SqlExpr> = mutableListOf(),
    val distinct: Boolean = false,
    val attributes: MutableMap<String, SqlExpr> = mutableMapOf(),
    val orderBy: MutableList<SqlOrderBy> = mutableListOf()
) : SqlExpr()

/**
 * sql语法树：函数表达式
 * @property name String 函数名称
 * @property args MutableList<SqlExpr> 参数列表
 */
data class SqlExprFunctionExpr(val name: String, var args: MutableList<SqlExpr> = mutableListOf()) : SqlExpr()

/**
 * sql语法树：CAST表达式
 * @property expr SqlExpr 需要转换类型的表达式
 * @property type String 需要转换成的类型
 */
data class SqlCastExpr(val expr: SqlExpr, val type: String) : SqlExpr()

/**
 * sql语法树：子查询表达式
 * @property query SqlSelectQuery 子查询
 */
data class SqlSelectQueryExpr(val query: SqlSelectQuery) : SqlExpr()

/**
 * sql语法树：IN 表达式
 * @property expr SqlExpr IN表达式左侧表达式
 * @property inExpr SqlExpr IN表达式右侧表达式
 * @property isNot Boolean 是否为NOT
 */
data class SqlInExpr(val expr: SqlExpr, val inExpr: SqlExpr, val isNot: Boolean = false) : SqlExpr()

/**
 * sql语法树：BETWEEN表达式
 * @property expr SqlExpr BETWEEN表达式左侧表达式
 * @property start T AND左侧表达式
 * @property end T AND右侧表达式
 * @property isNot Boolean 是否为NOT
 */
data class SqlBetweenExpr<T : SqlExpr>(val expr: SqlExpr, val start: T, val end: T, val isNot: Boolean = false) :
    SqlExpr()

/**
 * sql语法树：窗口函数表达式
 * @property aggFun SqlAggFunctionExpr 引用的聚合函数
 * @property partitionBy MutableList<SqlExpr> PARTITION BY列表
 * @property orderBy MutableList<SqlOrderBy> 排序规则列表
 */
data class SqlOverExpr(
    val aggFun: SqlAggFunctionExpr,
    val partitionBy: MutableList<SqlExpr> = mutableListOf(),
    val orderBy: MutableList<SqlOrderBy> = mutableListOf()
) : SqlExpr()

/**
 * sql语法树：CASE WHEN表达式
 * @property caseList MutableList<SqlCase> CASE WHEN匹配列表
 * @property default SqlExpr ELSE中的默认值
 */
data class SqlCaseExpr(val caseList: MutableList<SqlCase> = mutableListOf(), val default: SqlExpr) : SqlExpr()

/**
 * sql语法树：子查询谓词表达式（EXISTS、NOT EXISTS、ANY、ALL、SOME）
 * @property select SqlSelectQueryExpr 引用的子查询
 * @property predicate SqlSubQueryPredicate 子查询谓词
 */
data class SqlSubQueryPredicateExpr(val select: SqlSelectQueryExpr, val predicate: SqlSubQueryPredicate) : SqlExpr()